package com.zhijl.common.encryptor.asymmetric;

import org.bouncycastle.math.ec.ECPoint;

import java.math.BigInteger;

/**
 * sm2相关算法
 *
 * @author wind
 * @date   2017/7/29
 *
 * 证书代码整理 liu -> 2017/06/08
 */
public interface SM2 {

    /**
     * 国密标准默认ida
     */
    String DEFAULT_IDA = "1234567812345678";

    /**
     * 生成sm2密钥对
     *
     * @return sm2公私钥对
     */
    SM2KeyPair generateValidKeyPair();

    /**
     * 签名
     *
     * @param keyPair 签名方密钥对
     * @param msg     待签名信息的byte数组。 一般建议采用utf-8获取
     * @param IDA     签名方唯一标识。
     * @return 符合ASN.1编码格式的签名数据的字节数组
     */
    byte[] sign(SM2KeyPair keyPair, byte[] msg, String IDA);

    /**
     * 验签
     *
     * @param msg        签名信息的bytes数组. 一般建议采用utf-8获取
     * @param aPublicKey 签名方公钥
     * @param signData   符合ASN.1编码格式的签名数据的字节数组
     * @param IDA        签名方唯一标识
     * @return true or false
     */
    boolean verify(byte[] msg, ECPoint aPublicKey, byte[] signData, String IDA);


    /**
     * 采用公钥进行加密
     *
     * @param inputBuffer 加密数据
     * @param publicKey   公钥
     * @return            密文
     */
    byte[] encrypt(byte[] inputBuffer, ECPoint publicKey);

    /**
     * sm2解密
     *
     * @param encryptData 解密数据
     * @param privateKey  私钥
     * @return            明文
     */
    String decrypt(byte[] encryptData, BigInteger privateKey);

    /**
     * 公钥解析为hex字符串
     * 以未压缩形式对公钥编解码。04 || x的hex形式 || y的hex形式
     *
     * @param publicKey ECPoint格式公钥
     * @return          hex字符串格式格式公钥
     */
    String encodePublicKey(ECPoint publicKey);

    /**
     * hex字符串解析为公钥
     *
     * @param encodedKey hex字符串格式公钥
     * @return           ECPoint格式公钥
     */
    ECPoint decodePublicKey(String encodedKey);


    /**
     * 以未压缩形式对私钥钥编解码。
     * 大整数格式私钥转换为hex字符串私钥
     *
     * @param privateKey 私钥大整数
     * @return           hex私钥字符串
     */
    String encodePrivateKey(BigInteger privateKey);

    /**
     * hex字符串私钥转换为大整数类型私钥
     *
     * @param encodedKey hex字符串格式私钥
     * @return           大整数格式私钥
     */
    BigInteger decodePrivateKey(String encodedKey);

    /**
     * pem证书获取公钥
     * @param pemStr pem字符串
     * @return hex string 公钥
     * @exception RuntimeException 参数为null或empty/证书实例获取异常/证书获取失败
     */
    String pem2PubKey(String pemStr);

    /**
     * sk证书获取公私钥
     * @param skStr sk文件字符串
     * @return json hex pubKey&priKey string
     *              eg:
     *                  {"priKey":"...","pubKey":"...."}
     */
    String sk2PriKey(String skStr);

    /**
     * 生成sk和pem证书字符串
     * @return  json base64 cert String
     * @exception RuntimeException 证书相关异常...,异常发生表示生成失败
     */
    String genSelfedCert();

    /**
     * 生成指定cnname的自签名证书
     * @param CNName   自定义的cnname
     * @return         json base64 cert String
     *                 eg:
     *                   {"sk": "...","pem": "..."}
     *
     * @exception RuntimeException 证书相关异常...,异常发生表示生成失败
     */
    String genSelfedCert(String CNName);

    /**
     * Android移动端专用
     * 生成密码加密的自签名证书对
     * @param password  私钥加密的密码 [8,20]
     * @return          私钥sm4加密后的证书对象
     */
    SM2SelfedCert genSelfedCertWithPassword(String password);

    /**
     * Android移动端专用
     * 使用密码加密的私钥进行签名
     * @param enPriKey  密码加密后的私钥
     * @param password  加密密码
     * @param msg       加密消息
     * @return          hex String的签名结果
     */
    String signWithPassword(String enPriKey, String password, String msg);

    /**
     * Android移动端专用
     * 使用pem证书内容直接解析校验
     * @param msg           签名的消息
     * @param pemCert       pem证书内容
     * @param signData      签名的sign内容
     * @param IDA           签名的用户标示,一般使用DEFAULT_IDA
     * @return  检验结果 true/校验通过
     */
    boolean verifyByPemCert(String msg, String pemCert, String signData, String IDA);





}
